package dm.ast;

import test.envset.GlobalState;
import test.utility.Randomly;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import dm.ast.DmConstant.*;

/**
 * select语句中的orderby子句
 */
public class DmOrderby extends DmASTNode{

    public List<DmExpression> orderbyItems = null;
    private int itemSize = 0; //预计填入order by子句宽度

    String[] sort = {" desc" , " asc" , " "};
    String[] nullSort = { " NULLS FIRST" , " " , " NULLS LAST"};

    public DmOrderby() {
        orderbyItems = new ArrayList<DmExpression>();
    }

    public void setItemSize(int groups) {
        this.itemSize = groups;
    }

    public void addElement(DmExpression element){
        orderbyItems.add(element);
        //itemSize++;
    }

    public void setIntColumn(){
        orderbyItems = new ArrayList<>();
    }

    @Override
    public void fill(GlobalState globalState) {

    }

    @Override
    public void setWidt() {
        if(orderbyItems == null){
            wid_t = 0;
        }else {
            wid_t = itemSize; //未填充时，预计order by 子句深度
            for (int i = 0; i < orderbyItems.size(); i++) {
                wid_t = 0;
                orderbyItems.get(i).setWidt();
                wid_t += orderbyItems.get(i).wid_t;
            }
        }
    }

    @Override
    public void setDept() {
        if(orderbyItems == null){
            dep_t = 0;
        }else {
            dep_t = 1;
            for (int i = 0; i < orderbyItems.size(); i++) {
                orderbyItems.get(i).setDept();
                if(orderbyItems.get(i).dep_t > dep_t){
                    dep_t = orderbyItems.get(i).dep_t;
                }
            }
        }
    }

    @Override
    public DmDataType getExpressionType() {
        return null;
    }

    @Override
    public String toSql(){
        if(orderbyItems == null){
            return " " + this.getClass().getSimpleName();
        }else {
            StringBuilder sql = new StringBuilder();
            int idx = new Random().nextInt(sort.length);
            sql.append(" ORDER BY " + orderbyItems.get(0).toSql() + sort[idx] + nullSort[idx]);
            for (int i = 1; i < orderbyItems.size(); i++) {
                idx = new Random().nextInt(sort.length);
                sql.append(", " + orderbyItems.get(i).toSql() + sort[idx] + nullSort[idx]);
            }
            return sql.toString();
        }
    }

    //用查询列填充
    //返回orderby子句实际拥有的排序项数目
    public int fillBySelElement(GlobalState globalState , DmSelectElements selElements){
        if(selElements.elements.size() < itemSize){
            itemSize = selElements.elements.size();
        }
        //order by子句中填入IntDmConst 或 DmColumn
        boolean flag = Randomly.getBoolean();
        for (int m = 0; m < itemSize; m++) {
            if(flag){
                addIntCol(selElements);
            }else {
                DmExpression element = getRanSelCol(selElements);
                //boolean intFlag = element.getLeftExp() instanceof IntDmConst;
                boolean intFlag = element.toSql().matches("-?[0-9]+.?[0-9]*");
                if(element.getDept() == 1 && intFlag == false){
                    //将非子查询的查询列依次放入Order by排序项
                    orderbyItems.add(element);
                }
            }
        }
        return orderbyItems.size();
    }

    //int形式填充order by排序项
    public void addIntCol(DmSelectElements selElements){
        Randomly r = new Randomly();
        int num = r.getInteger(1 , selElements.elements_size);
        orderbyItems.add(new IntDmConst(num));
    }

    //随机返回查询项的其中一个列
    public DmExpression getRanSelCol(DmSelectElements selElements){
        List<DmExpression> cols = new ArrayList<>();
        cols.addAll(selElements.elements);
        if(cols.size() > 0){
            DmExpression col = null;
            col = Randomly.fromList(cols);
            cols.remove(col);
            return col;
        }else {
            return null;
        }
    }
}
